package com.cmas.platform.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.aidex.common.core.domain.R;
import com.aidex.common.exception.CustomException;
import com.aidex.common.utils.PageUtils;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.cmas.platform.common.annotation.OperatorDataScope;
import com.cmas.platform.domain.ApproveRecord;
import com.cmas.platform.domain.em.ApproveStatusEnum;
import com.cmas.platform.mapper.ApproveRecordMapper;
import com.cmas.platform.utils.ContentCheckUtil;
import com.cmas.platform.vo.CommentVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.aidex.common.utils.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cmas.platform.mapper.CommentMapper;
import com.cmas.platform.domain.Comment;
import com.cmas.platform.service.CommentService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 评论管理Service业务层处理
 *
 * @author su
 * @email 1218819874@qq.com
 * @date 2023-03-15
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    private static final Logger log = LoggerFactory.getLogger(CommentServiceImpl.class);


    @Autowired
    private ApproveRecordMapper approveRecordMapper;

    /**
     * 查询评论管理列表
     *
     * @param comment 评论管理
     * @return 评论管理
     */
    @OperatorDataScope(useType = "1",fieldName = "regionId")
    @Override
    public List<CommentVo> selectCommentVoList(CommentVo comment) {
        PageUtils.startPage();
        QueryWrapper<Comment> queryWrapper = setQueryWrapper(comment);
        return baseMapper.selectCommentVoList(queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public R<?> addComment(Comment comment) {
        R<?> checkResult = checkSensitiveWord(comment);
        R<?> result = new R<>(checkResult.getCode(), checkResult.getMsg());
        if (R.isSuccess(checkResult)) {
            R<Comment> censorResult = automaticApprove(comment);
            result.setCode(censorResult.getCode());
            result.setMsg(censorResult.getMsg());
            if (R.isSuccess(censorResult)) {
                saveComment(censorResult);
            }
        }
        return result;
    }

    /**
     * 保存评论
     *
     * @param dataResult
     */

    public void saveComment(R<Comment> dataResult) {
        Comment comment = dataResult.getData();
        if (StringUtils.isNotEmpty(comment.getPid())) {
            baseMapper.update(null, new UpdateWrapper<Comment>().lambda()
                    .eq(Comment::getId, comment.getPid())
                    .set(Comment::getIsChild, "1"));
        }
        baseMapper.insert(comment);
        ApproveRecord approveRecord = new ApproveRecord();
        approveRecord.setBeforeStatus("0");
        approveRecord.setReason(dataResult.getMsg());
        setSuccessApproveRecord(comment, approveRecord);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public R<?> updateComment(Comment comment) {
        String beforeStatus = comment.getStatus();
        R<?> checkResult = checkSensitiveWord(comment);
        R<?> result = new R<>(checkResult.getCode(), checkResult.getMsg());
        if (R.isSuccess(checkResult)) {
            R<Comment> censorResult = automaticApprove(comment);
            result.setCode(censorResult.getCode());
            result.setMsg(censorResult.getMsg());
            if (R.isSuccess(censorResult)) {
                modifyComment(censorResult, beforeStatus);
            }
        }
        return result;
    }

    /**
     * 修改评论
     *
     * @param dataResult
     * @param beforeStatus
     */
    public void modifyComment(R<Comment> dataResult, String beforeStatus) {
        Comment comment = dataResult.getData();
        Comment oldComment = baseMapper.selectById(comment.getId());
        //当前pid为空，旧数据pid不为空，修改旧pid评论节点
        if (StringUtils.isEmpty(comment.getPid()) && StringUtils.isNotEmpty(oldComment.getPid())) {
            comment.setPid(null);
            updateOldParentNode(new String[]{oldComment.getPid()});
        } else if (StringUtils.isNotEmpty(comment.getPid())) {
            //当前pid和旧pid不一致，修改当前pid评论节点和旧pid评论节点
            if (!oldComment.getPid().equals(comment.getPid())) {
                baseMapper.update(null, new UpdateWrapper<Comment>().lambda()
                        .eq(Comment::getId, comment.getPid())
                        .set(Comment::getIsChild, "1"));
                updateOldParentNode(new String[]{oldComment.getPid()});
            }
        }
        baseMapper.updateById(comment);
        ApproveRecord approveRecord = new ApproveRecord();
        approveRecord.setBeforeStatus(beforeStatus);
        approveRecord.setReason(dataResult.getMsg());
        setSuccessApproveRecord(comment, approveRecord);
    }


    /**
     * 设置通过审核记录
     *
     * @param comment
     * @param approveRecord
     */
    public void setSuccessApproveRecord(Comment comment, ApproveRecord approveRecord) {
        approveRecord.setItemTableName(SqlHelper.table(Comment.class).getTableName());
        approveRecord.setType("0");
        approveRecord.setItemId(comment.getId());
        approveRecord.setAfterStatus(comment.getStatus());
        approveRecordMapper.insert(approveRecord);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approve(ApproveRecord approveRecord) {
        Comment comment = baseMapper.selectById(approveRecord.getItemId());
        approveRecord.setItemTableName(SqlHelper.table(Comment.class).getTableName());
        approveRecord.setBeforeStatus(comment.getStatus());
        if (approveRecord.getType().equals("0")) {
            comment.setStatus(ApproveStatusEnum.ARTIFICIAL_PASS.getValue());
        } else if (approveRecord.getType().equals("1")) {
            comment.setStatus(ApproveStatusEnum.ARTIFICIAL_REJECT.getValue());
        }
        baseMapper.updateById(comment);
        approveRecord.setAfterStatus(comment.getStatus());
        approveRecordMapper.insert(approveRecord);
    }


    /**
     * 自动审核通过调用百度api
     *
     * @param comment
     * @return
     */
    public R<Comment> automaticApprove(Comment comment) {
        R<Integer> censorResult = ContentCheckUtil.getCommonTextCensorResult(comment.getContent());
        R<Comment> result = new R<>(censorResult.getCode(), censorResult.getMsg());
        int conclusionType = censorResult.getData();
        if (conclusionType == ContentCheckUtil.CENSOR_SUCCESS) {
            comment.setStatus(ApproveStatusEnum.AUTOMATIC_PASS.getValue());
        } else if (conclusionType == ContentCheckUtil.CENSOR_ERROR) {
            comment.setStatus(ApproveStatusEnum.ARTIFICIAL_AUDIT.getValue());
        } else {
            comment.setStatus(ApproveStatusEnum.AUTOMATIC_REJECT.getValue());
        }
        result.setData(comment);
        return result;
    }

    /**
     * 敏感词检测
     *
     * @param comment
     * @return
     */
    private R<?> checkSensitiveWord(Comment comment) {
        R<?> contentCheck = ContentCheckUtil.checkBySensitiveWord(comment.getContent());
        if (R.isError(contentCheck)) {
            return R.fail("内容" + contentCheck.getMsg());
        }
        return R.success("操作成功");
    }


    @Override
    public List<Comment> selectCommentList(Comment comment) {
        CommentVo commentVo=new CommentVo();
        BeanUtils.copyProperties(comment,commentVo);
        QueryWrapper<Comment> queryWrapper = setQueryWrapper(commentVo);
        return baseMapper.selectList(queryWrapper);
    }


    public QueryWrapper<Comment> setQueryWrapper(CommentVo comment) {
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(comment.getRegionId())){
            queryWrapper.eq("p.region_id", comment.getRegionId());
        }
        if (StringUtils.isNotEmpty(comment.getId())
                && StringUtils.isEmpty(comment.getStatus())) {
            queryWrapper.eq("cmas.comment.id", comment.getId());
        }
        if (StringUtils.isNotEmpty(comment.getPid())) {
            queryWrapper.eq("cmas.comment.pid", comment.getPid());
        }
        if (StringUtils.isNotEmpty(comment.getPostId())) {
            queryWrapper.eq("cmas.comment.post_id", comment.getPostId());
        }
        if (StringUtils.isNotEmpty(comment.getUserId())) {
            queryWrapper.eq("cmas.comment.user_id", comment.getUserId());
        }
        if (StringUtils.isNotEmpty(comment.getContent())) {
            queryWrapper.like("cmas.comment.content", comment.getContent());
        }
        if (StringUtils.isNotEmpty(comment.getIsChild())) {
            queryWrapper.eq("cmas.comment.is_child", comment.getIsChild());
        }
        if (StringUtils.isNotEmpty(comment.getStatus())) {
            String[] statusList = comment.getStatus().split(",");
            if (statusList.length > 1) {
                if (StringUtils.isNotEmpty(comment.getId())) {
                    queryWrapper.ne("cmas.comment.id", comment.getId());
                }
                queryWrapper.in("cmas.comment.status", statusList);
            } else {
                queryWrapper.eq("cmas.comment.status", comment.getStatus());
            }
        }
        return queryWrapper;
    }


    /**
     * 批量删除评论管理
     *
     * @param ids 需要删除的评论管理ID
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteCommentByIds(String[] ids) {
        //查询选中节点下所有子节点一并删除
        String treeIds = queryTreeChildIds(ids);
        if (treeIds.indexOf(",") > 0) {
            StringBuffer pidSb = new StringBuffer();
            String[] idArr = treeIds.split(",");
            for (String idVal : idArr) {
                if (idVal != null) {
                    Comment comment = baseMapper.selectById(idVal);
                    String pidVal = comment.getPid();
                    //查询此节点上一级是否还有其他子节点
                    List<Comment> dataList = baseMapper.selectList(new QueryWrapper<Comment>().lambda()
                            .eq(Comment::getPid, pidVal)
                            .notIn(Comment::getId, Arrays.asList(idArr)));
                    if (dataList.isEmpty() && !Arrays.asList(idArr).contains(pidVal)
                            && (pidSb.length() > 0 && !pidSb.toString().contains(pidVal))) {
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        pidSb.append(pidVal).append(",");
                    }
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(Arrays.asList(idArr));
            //修改已无子节点的标识
            updateOldParentNode(pidSb.toString().split(","));
        } else {
            Comment comment = baseMapper.selectById(treeIds);
            if (comment == null) {
                throw new CustomException("未找到对应实体");
            }
            updateOldParentNode(new String[]{comment.getPid()});
            baseMapper.deleteById(treeIds);
        }
    }


    /**
     * 根据所传父id数组查询旧的父级节点的子节点并修改相应状态值
     *
     * @param pidArr
     */
    public void updateOldParentNode(String[] pidArr) {
        List<String> batchIdList = new ArrayList<>();
        for (String pid : pidArr) {
            Integer count = baseMapper.selectCount(new QueryWrapper<Comment>()
                    .lambda().eq(Comment::getPid, pid));
            if (count == null || count <= 1) {
                batchIdList.add(pid);
            }
        }
        if (!batchIdList.isEmpty()) {
            baseMapper.update(null, new UpdateWrapper<Comment>().lambda()
                    .in(Comment::getId, batchIdList)
                    .set(Comment::getIsChild, "0")
            );
        }
    }


    /**
     * 根据id查询所有子节点id
     *
     * @param ids
     * @return
     */
    private String queryTreeChildIds(String[] ids) {
        //获取待id数组
        StringBuffer sb = new StringBuffer();
        for (String pidVal : ids) {
            if (pidVal != null) {
                if (!sb.toString().contains(pidVal)) {
                    if (!sb.toString().isEmpty()) {
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    getTreeChildIds(pidVal, sb);
                }
            }
        }
        return sb.toString();
    }

    private StringBuffer getTreeChildIds(String pidVal, StringBuffer sb) {
        List<Comment> dataList = baseMapper.selectList(new QueryWrapper<Comment>().eq("pid", pidVal));
        if (dataList != null && !dataList.isEmpty()) {
            for (Comment tree : dataList) {
                if (!sb.toString().contains(tree.getId())) {
                    sb.append(",").append(tree.getId());
                }
                getTreeChildIds(tree.getId(), sb);
            }
        }
        return sb;
    }

}
